'use strict';

var Enum = require('enum');

var ZNP = {};

ZNP.Capabilities = new Enum({
  MT_CAP_SYS:  0x0001,
  MT_CAP_MAC:  0x0002,
  MT_CAP_NWK:  0x0004,
  MT_CAP_AF:   0x0008,
  MT_CAP_ZDO:  0x0010,
  MT_CAP_SAPI: 0x0020,
  MT_CAP_UTIL: 0x0040,
  MT_CAP_DEBUG:0x0080,
  MT_CAP_APP:  0x0100,
  MT_CAP_ZOAD: 0x1000,
});

ZNP.CommandType = new Enum({
  POLL: 0x00,
  SREQ: 0x20,
  AREQ: 0x40,
  SRSP: 0x60,
});

ZNP.CommandSubsystem = new Enum({
  RPCError: 0x00,
  SYS: 0x01,
  MAC: 0x02, // not available on ZNP
  NWK: 0x03, // not available on ZNP
  AF: 0x04,
  ZDO: 0x05,
  ZB: 0x06, // alternate name, prefixes the actual commands
  SAPI: 0x06,
  UTIL: 0x07,
  DEBUG: 0x08,
  APP: 0x09,
});

ZNP.AddressMode = new Enum({
  ADDR_16_BIT: 0x02,
  ADDR_BROADCAST: 0xFF
});

ZNP.Commands = {};

ZNP.Commands.AF = new Enum({
  AF_REGISTER: 0x00,
  AF_DATA_REQUEST: 0x01,
  AF_DATA_REQUEST_EXT: 0x02,

  AF_DATA_CONFIRM: 0x80,
  AF_INCOMING_MSG: 0x81
});

ZNP.Commands.SYS = new Enum({
  // app -> ZNP
  SYS_RESET_REQ: 0x00,
  SYS_PING: 0x01,
  SYS_VERSION: 0x02,
  SYS_SET_EXTADDR: 0x03,
  SYS_GET_EXTADDR: 0x04,
  SYS_RAM_READ: 0x05,
  SYS_RAM_WRITE: 0x06,
  SYS_OSAL_NV_ITEM_INIT: 0x07,
  SYS_OSAL_NV_READ: 0x08,
  SYS_OSAL_NV_WRITE: 0x09,
  SYS_OSAL_START_TIMER: 0x0A,
  SYS_OSAL_STOP_TIMER: 0x0B,
  SYS_RANDOM: 0x0C,
  SYS_ADC_READ: 0x0D,
  SYS_GPIO: 0x0E,
  SYS_STACK_TUNE: 0x0F,
  SYS_SET_TIME: 0x10,
  SYS_GET_TIME: 0x11,
  SYS_OSAL_NV_DELETE: 0x12,
  SYS_OSAL_NV_LENGTH: 0x13,
  SYS_SET_TX_POWER: 0x14,

  // ZNP -> app
  SYS_RESET_IND: 0x80,
  SYS_OSAL_TIMER_EXPIRED: 0x81,
});

ZNP.Commands.MAC = new Enum({
  // app -> ZNP
  MAC_RESET_REQ: 0x01,
  MAC_INIT: 0x02,
  MAC_START_REQ: 0x03,
  MAC_SYNC_REQ: 0x04,
  MAC_DATA_REQ: 0x05,
  MAC_ASSOCIATE_REQ: 0x06,
  MAC_DISASSOCIATE_REQ: 0x07,
  MAC_GET_REQ: 0x08,
  MAC_SET_REQ: 0x09,
  MAC_SCAN_REQ: 0x0C,
  MAC_POLL_REQ: 0x0D,
  MAC_PURGE_REQ: 0x0E,
  MAC_SET_RX_GAIN_REQ: 0x0F,
  MAC_ASSOCIATE_RSP: 0x50,
  MAC_ORPHAN_RSP: 0x51,

  // ZNP -> app
  MAC_SYNC_LOSS_IND: 0x80,
  MAC_ASSOCIATE_IND: 0x81,
  MAC_ASSOCIATE_CNF: 0x82,
  MAC_BEACON_NOTIFY_IND: 0x83,
  MAC_DATA_CNF: 0x84,
  MAC_DATA_IND: 0x85,
  MAC_DISASSOCIATE_IND: 0x86,
  MAC_DISASSOCIATE_CNF: 0x87,
  MAC_ORPHAN_IND: 0x8A,
  MAC_POLL_CNF: 0x8B,
  MAC_SCAN_CNF: 0x8C,
  MAC_COMM_STATUS_IND: 0x8D,
  MAC_START_CNF: 0x8E,
  MAC_RX_ENABLE_CNF: 0x8F,
  MAC_PURGE_CNF: 0x9A,
});

ZNP.Commands.ZDO = new Enum({
  ZDO_NWK_ADDR_REQ: 0x00,
  ZDO_IEEE_ADDR_REQ: 0x01,
  ZDO_NODE_DESC_REQ: 0x02,
  ZDO_POWER_DESC_REQ: 0x03,
  ZDO_SIMPLE_DESC_REQ: 0x04,
  ZDO_ACTIVE_EP_REQ: 0x05,
  ZDO_MATCH_DESC_REQ: 0x06,
  ZDO_COMPLEX_DESC_REQ: 0x07,
  ZDO_USER_DESC_REQ: 0x08,
  ZDO_END_DEV_ANNCE: 0x0A,
  ZDO_USER_DESC_SET: 0x0B,
  ZDO_SERVICE_DISC_REQ: 0x0C,
  ZDO_END_DEVICE_TIMEOUT_REQ: 0x0D,

  ZDO_END_DEV_BIND_REQ: 0x20,
  ZDO_BIND_REQ: 0x21,
  ZDO_UNBIND_REQ: 0x22,
  ZDO_SET_LINK_KEY: 0x23,
  ZDO_REMOVE_LINK_KEY: 0x24,
  ZDO_GET_LINK_KEY: 0x25,
  ZDO_NWK_DISCOVERY_REQ: 0x26,
  ZDO_JOIN_REQ: 0x27,
  ZDO_SEND_DATA: 0x28,
  ZDO_NWK_ADDR_OF_INTEREST_REQ: 0x29,
  ZDO_MGMT_NWKDISC_REQ: 0x30,
  ZDO_MGMT_LQI_REQ: 0x31,
  ZDO_MGMT_RTG_REQ: 0x32,
  ZDO_MGMT_BIND_REQ: 0x33,
  ZDO_MGMT_LEAVE_REQ: 0x34,
  ZDO_MGMT_DIRECT_JOIN_REQ: 0x35,
  ZDO_MGMT_PERMIT_JOIN_REQ: 0x36,
  ZDO_MGMT_NWK_UPDATE_REQ: 0x37,

  ZDO_MSG_CB_REGISTER: 0x3E,
  ZDO_MSG_CB_REMOVE: 0x3F,
  ZDO_STARTUP_FROM_APP: 0x40,

  ZDO_AUTO_FIND_DESTINATION_REQ: 0x41,
  ZDO_SEC_ADD_LINK_KEY: 0x42,
  ZDO_SEC_ENTRY_LOOKUP_EXT: 0x43,
  ZDO_SEC_DEVICE_REMOVE: 0x44,
  ZDO_EXT_ROUTE_DISC: 0x45,
  ZDO_EXT_ROUTE_CHECK: 0x46,
  ZDO_EXT_REMOVE_GROUP: 0x47,
  ZDO_EXT_REMOVE_ALL_GROUP: 0x48,
  ZDO_EXT_FIND_ALL_GROUPS_ENDPOINT: 0x49,
  ZDO_EXT_FIND_GROUP: 0x4A,
  ZDO_EXT_ADD_GROUP: 0x4B,
  ZDO_EXT_COUNT_ALL_GROUPS: 0x4C,

  ZDO_MGMT_PERMIT_JOIN_RSP: 0xB6,

  ZDO_STATE_CHANGE_IND: 0xC0,
  ZDO_END_DEVICE_ANNCE_IND: 0xC1,
  ZDO_MATCH_DESC_RSP_SENT: 0xC2,
  ZDO_STATUS_ERROR_RSP: 0xC3,
  ZDO_SRC_RTG_IND: 0xC4,
  ZDO_BEACON_NOTIFY_IND: 0xC5,
  ZDO_JOIN_CNF: 0xC6,
  ZDO_NWK_DISCOVERY_CNF: 0xC7,
  ZDO_CONCENTRATOR_IND_CB: 0xC8,
  ZDO_LEAVE_IND: 0xC9,


  ZDO_RESPONSE_BIT: 0x8000,

  ZDO_SIMPLE_DESC_RSP: 0x84,
  ZDO_ACTIVE_EP_RSP: 0x85,
  ZDO_MATCH_DESC_RSP: 0x86,
  ZDO_COMPLEX_DESC_RSP: 0x90

  /* incomplete */
});

ZNP.Commands.UTIL = new Enum({
  UTIL_GET_DEVICE_INFO: 0x00,
  UTIL_ADDRMGR_NWK_ADDR_LOOKUP: 0x41,
  UTIL_ASSOC_COUNT: 0x48,
  UTIL_ASSOC_FIND_DEVICE: 0x49,
  UTIL_ASSOC_GET_WITH_ADDRESS: 0x4A,

  /* incomplete */
});

ZNP.Commands.ZB = new Enum({
  ZB_START_REQUEST: 0x00,
  ZB_WRITE_CONFIGURATION: 0x05,
  ZB_PERMIT_JOINING_REQUEST: 0x08,
  ZB_APP_REGISTER_REQUEST: 0x0A,

  ZB_START_CONFIRM: 0x80,

  /* incomplete */
});


ZNP.ConfigurationParameters = {};

ZNP.ConfigurationParameters.ZCD = new Enum({
  ZCD_NV_STARTUP_OPTION: 0x0003,
  ZCD_NV_PRECFGKEY: 0x0062,
  ZCD_NV_PRECFGKEYS_ENABLE: 0x0063,
  ZCD_NV_SECURITY_MODE: 0x0064,
  ZCD_NV_PANID: 0x0083,
  ZCD_NV_CHANLIST: 0x0084,
  ZCD_NV_LOGICAL_TYPE: 0x0087,
  ZCD_NV_ZDO_DIRECT_CB: 0x008F,

  /* incomplete */
});

// CC2530ZNP Interface Specification.pdf
// 4.7 Return Values
ZNP.Status = new Enum({
  ZSuccess: 0x00,
  ZFailure: 0x01,
  ZInvalidParameter: 0x02,
  NV_ITEM_UNINIT: 0x09,
  NV_OPER_FAILED: 0x0a,
  NV_BAD_ITEM_LEN: 0x0c,
  ZMemError: 0x10,
  ZBufferFull: 0x11,
  ZUnsupportedMode: 0x12,
  ZMacMemError: 0x13,
  zdoInvalidRequestType: 0x80,
  zdoInvalidEndpoint: 0x82,
  zdoUnsupported: 0x84,
  zdoTimeout: 0x85,
  zdoNoMatch: 0x86,
  zdoTableFull: 0x87,
  zdoNoBindEntry: 0x88,
  ZSecNoKey: 0xa1,
  ZSecMaxFrmCount: 0xa3,
  ZApsFail: 0xb1,
  ZApsTableFull: 0xb2,
  ZApsIllegalRequest: 0xb3,
  ZApsInvalidBinding: 0xb4,
  ZApsUnsupportedAttrib: 0xb5,
  ZApsNotSupported: 0xb6,
  ZApsNoAck: 0xb7,
  ZApsDuplicateEntry: 0xb8,
  ZApsNoBoundDevice: 0xb9,
  ZNwkInvalidParam: 0xc1,
  ZNwkInvalidRequest: 0xc2,
  ZNwkNotPermitted: 0xc3,
  ZNwkStartupFailure: 0xc4,
  ZNwkTableFull: 0xc7,
  ZNwkUnknownDevice: 0xc8,
  ZNwkUnsupportedAttribute: 0xc9,
  ZNwkNoNetworks: 0xca,
  ZNwkLeaveUnconfirmed: 0xcb,
  ZNwkNoAck: 0xcc,
  ZNwkNoRoute: 0xcd,
  ZMacNoACK: 0xe9
});

ZNP.LogicalType = new Enum({
  COORDINATOR: 0x00,
  ROUTER: 0x01,
  ENDDEVICE: 0x02
});

ZNP.Channel = new Enum({
  NONE: 0x00000000,
  ALL_CHANNELS: 0x07FFF800,
  CHANNEL_11: 0x800,
  CHANNEL_12: 0x1000,
  CHANNEL_13: 0x2000,
  CHANNEL_14: 0x4000,
  CHANNEL_15: 0x8000,
  CHANNEL_16: 0x10000,
  CHANNEL_17: 0x20000,
  CHANNEL_18: 0x40000,
  CHANNEL_19: 0x80000,
  CHANNEL_20: 0x100000,
  CHANNEL_21: 0x200000,
  CHANNEL_22: 0x400000,
  CHANNEL_23: 0x800000,
  CHANNEL_24: 0x1000000,
  CHANNEL_25: 0x2000000,
  CHANNEL_26: 0x4000000
});

ZNP.ZDOState = new Enum({
  DEV_HOLD: 0,
  DEV_INIT: 1,
  DEV_NWK_DISC: 2,
  DEV_NWK_JOINING: 3,
  DEV_NWK_REJOIN: 4,
  DEV_END_DEVICE_UNAUTH: 5,
  DEV_END_DEVICE: 6,
  DEV_ROUTER: 7,
  DEV_COORD_STARTING: 8,
  DEV_ZB_COORD: 9,
  DEV_NWK_ORPHAN: 10,
});

ZNP.StartupOption = new Enum({
  STARTOPT_CLEAR_CONFIG: 0x01,
  STARTOPT_CLEAR_STATE:  0x02,
});

ZNP.NodeRelation = new Enum({
  PARENT: 0,
  CHILD_RFD: 1,
  CHILD_RFX_RXONWHENIDLE: 2,
  CHILD_FFD: 3,
  CHILD_FFD_RXONWHENIDLE: 4,
  NEIGHBOR: 5,
  OTHER: 6,
});

module.exports = ZNP;
